package com.gonsin.license.processors;

import com.gonsin.license.*;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.gonsin.license.GLicenseAutoSelector.DEVICE;

/**
 * 本地授权逻辑，如果本地授权文件存在，则运行该流程
 */
@Slf4j
@Component
public class LicenseRemoteProcessor {

    @Value("${com.gonsin.license.licenseServer:http://update.gonsincloud.com}")
    private String licenseServer;

    @Getter
    @Value("${com.gonsin.license.filePath:/home/gonsin/}")
    private String filePath = "/home/gonsin/";

    @Autowired
    private LicenseLocalProcessor localProcessor;

    /**
     * 本地授权检测
     */
    public boolean validateLicense(String uuid) throws Exception {

        // 解码逻辑
        // 1、读取授权文件原文，并进行AES解码，秘钥为 gonsin ，偏移量 为 gonsin
        // 2、解码后的内容，末尾32个字符，为本设备的uuid(大写)
        // 3、去除末尾的32个字符，之后剩余的内容，再进行一次AES解码，秘钥为gonsin，偏移量为 gonsin
        // 4、以上2次解码后的内容，是一个json字符串，里面包含的就是授权所有的信息，其结构如下
        /*
         {
            "device": "",           // 设备的32位 uuid
            "type": "",             // 设备的device类型，例如venus
            "validate": ""          // 设备的授权时间，如果是 "forever" ，表示 永久，如果取值为 具体时间（例如 "2024/7/25"），就表示该天的24点之后就授权失效
            "extra":""              // 20240715新增extra字段，用于客户端自行定义额外功能，客户端可以填充例如授权功能列表，各个权限开通的时间等。
            "version": ""           // 20240715新增version字段，用于标记该json文件的格式，初始版本为“v1-20240715”表示从20240715开始标记的v1版本，
                                    // 后续该json格式有更改的话，应该为“v2-更改的日期”
         }
         */
        // 5、一旦授权检测到授权是有效的，需要修改 licensed为true，让过滤器可以通过所有请求。


        String device = DEVICE;
        CloseableHttpClient client = HttpClientBuilder.create().build();
        long now = System.currentTimeMillis();
        HttpPost post = new HttpPost(licenseServer + "/api/getLicense/uuid");

        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("uuid", uuid));
        LicenseResponse response = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(params));
            response = client.execute(post, response1 -> {
                InputStream input = response1.getEntity().getContent();

                StringBuilder sb = new StringBuilder();
                String line;
                BufferedReader br = new BufferedReader(new InputStreamReader(input));
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                String str = sb.toString();
//                if(LOG){
//                    log.info("返回：" + str);
//                }

                JsonParser parser = new JsonParser();
                JsonElement element = parser.parse(str);
                JsonObject responseJson = element.getAsJsonObject();
                if(responseJson == null){
                    return null;
                }
                int status = responseJson.get("status").getAsInt();
                if(status != 200){
                    return null;
                }

                JsonObject dataJson = responseJson.get("data").getAsJsonObject();
                String licenseKey = dataJson.get("licenseKey").getAsString();
                String date = dataJson.get("date").getAsString();
                String company = dataJson.get("company").getAsString();
                String uuidFromServer = dataJson.get("uuid").getAsString();
                String type = dataJson.get("device").getAsString();
                String licenseUrl = dataJson.get("licenseUrl").getAsString();

                LicenseResponse licenseResponse = new LicenseResponse();
                licenseResponse.setCompany(company);
                licenseResponse.setDate(date);
                licenseResponse.setStatus(200);
                licenseResponse.setUuid(uuidFromServer);
                licenseResponse.setDevice(type);
                licenseResponse.setLicenseUrl(licenseUrl);
                return licenseResponse;
            });
        } catch (Exception e) {
            log.error(e.toString(), e);
        }

        if(response == null){
            return false;
        }

        if(response.getStatus() != 200){
            return false;
        }

        // 比较本地信息
        if(!device.equals(response.getDevice())){
            return false;
        }
        if(!uuid.equals(response.getUuid())){
            return false;
        }
        if(!response.getDate().equals("forever")){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            Date date = null;
            try {
                date = sdf.parse(response.getDate());
                if(date.getTime() < System.currentTimeMillis()){
                    return false;
                }
            } catch (ParseException e) {
                log.error(e.toString(), e);
            }
        }

        // 授权成功，将授权文件下载到本地
        if(HttpUtils.downloadFile(licenseServer + response.getLicenseUrl(),
                filePath + "license/" + DEVICE + "_license")){
            File licenseFile = new File(filePath + "license/" + DEVICE + "_license");
            if(localProcessor.validateLicense(uuid, licenseFile)){
                return true;
            }
            licenseFile.delete();
            return false;
        }
        return false;
    }
}
